home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
vol_400
/
422_02
/
dosutil
/
stuff.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-20
|
5KB
|
181 lines
/*
* Keyboard buffer stuffer
*
* This program copies characters from the command line into the PC
* keyboard buffer, adding correct "scan code" extensions as it does so.
* Numerous "escape sequences" are recognized to provide for stuffing
* non-ASCII characters produced by the various non-alphanumeric keys on
* the PC keyboard.
*
* The default BIOS keyboard buffer holds only 15 entries, however this
* program uses the START/END pointers from BIOS, so it should work
* correctly with the various utilities that enlarge the buffer.
*
* Copyright 1994 Dave Dunfield
* All rights reserved.
*
* Permission granted for personal (non-commerical) use only.
*
* Compile command: CC stuff -fop
*/
#include <stdio.h>
#define BIOS_SEG 0x40 /* BIOS data segment */
#define BUFFER_START 0x80 /* Pointer to start of keyboard buffer */
#define BUFFER_END 0x82 /* Pointer to end of keyboard buffer */
#define BUFFER_TAIL 0x1A /* Pointer to next character to receive */
#define BUFFER_HEAD 0x1C /* Pointer to first available spot */
/* Prefix codes for "ALPHA" keys */
char alpha_prefix[] = {
0x1E, 0x30, 0x2E, 0x20, 0x12, 0x21, 0x22, 0x23, 0x17, 0x24,
0x25, 0x26, 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1F, 0x14,
0x16, 0x2F, 0x11, 0x2D, 0x15, 0x2C };
/* Codes for misc. ASCII keys */
unsigned ascii_prefix[] = {
0x3920, 0x0231, 0x0332, 0x0433, 0x0534, 0x0635, 0x0736, 0x0837,
0x0938, 0x0A39, 0x0B30, 0x0C2D, 0x0D3D, 0x2B5C, 0x297E, 0x0221,
0x0340, 0x0423, 0x0524, 0x0625, 0x0826, 0x092A, 0x0A28, 0x0B29,
0x0C5F, 0x0D2B, 0x2B7C, 0x1A5B, 0x1B5D, 0x273B, 0x2827, 0x332C,
0x342E, 0x352F, 0x1A7B, 0x1B7D, 0x273A, 0x2822, 0x333C, 0x343E,
0x353F, 0x2960, 0 };
/* Table of special keys & codes */
char misc_key[] = {
'=', '!', '/', '\\', /* Enter, Backspace, Tab, Backtab */
'@','#','$', '+', '-', /* Escape, Ins, Del, keypad+, keypad- */
'<', '>', '{', '}', /* Right, Left, Up, Down */
'(', ')', '[', ']', /* Home, End, PgUp, PgDn */
'^' }; /* Single '^' */
unsigned misc_code[] = {
0x1C0D, 0x0E08, 0x0F09, 0x0F00,
0x011B, 0x5200, 0x5300, 0x4E2b, 0x4A2D,
0x4B00, 0x4D00, 0x4800, 0x5000,
0x4700, 0x4F00, 0x4900, 0x5100,
0x075E };
/* Help text */
char *help[] = {
"\nKeyboard buffer stuffer - by Dave Dunfield\n",
"\nUse: stuff <characters>\n\n",
"^ indicates special characters:\n\n",
" ^A-Z Ctrl ^*A-Z Alt ^.0-9 Fn ^,0-9 SFn ^:0-9 CFn ^;0-9 AFn\n\n",
" ^^ (^) ^= Enter ^@ Esc ^! Backsp ^/ Tab ^\\ Backtab\n",
" ^< Right ^> Left ^{ Up ^} Down ^[ PgUp ^] PgDn\n",
" ^( Home ^) End ^+ Kpad+ ^- Kpad- ^# Ins ^$ Del\n",
" ^? Clear keyboard buffer\n",
0 };
/*
* Main program - Stuff arguments into the keyboard buffer
*/
main(argc, argv)
int argc;
char *argv[];
{
int i;
if(argc < 2) { /* No data to stuff, display help */
for(i=0; help[i]; ++i)
fputs(help[i], stdout);
return; }
i = 1;
while(i < argc) { /* Stuff all arguments */
stuff_string(argv[i]);
if(++i < argc)
stuff_string(" "); }
}
/*
* Stuff a string into the keyboard buffer
*/
stuff_string(ptr)
char *ptr;
{
int i, j;
char c, prefix;
while(c = *ptr++) {
if(isalpha(c)) /* Normal "ALPHA" character */
prefix = alpha_prefix[(c & 0x1F) - 1];
else if(c == '^') {
if(isalpha(c = *ptr++)) /* ALPHA control code */
prefix = alpha_prefix[(c &= 0x1F) - 1];
else switch(c) {
default:
for(i=0; i < sizeof(misc_key); ++i)
if(c == misc_key[i]) {
stuff_key(misc_code[i]);
goto done; }
clear_buffer();
abort("Unknown ^!\n");
case '.' : /* Normal function key */
prefix = 0x3B;
goto dofunc;
case ',' : /* Shift function key */
prefix = 0x54;
goto dofunc;
case ':' : /* CTRL function key */
prefix = 0x5E;
goto dofunc;
case ';' : /* ALT function key */
prefix = 0x68;
dofunc:
if(isdigit(c = *ptr++)) {
prefix += (c == '0') ? 9 : (c - '1');
c = 0;
break; }
clear_buffer();
abort("Fkey must be 0-9\n");
case '?' : /* Clear buffer */
clear_buffer();
continue;
case '*' : /* ALT-ALPHA character */
prefix = alpha_prefix[(*ptr++ & 0x1F) - 1];
c = 0; } }
else {
for(i=0; j = ascii_prefix[i]; ++i)
if((j & 255) == c) {
stuff_key(j);
goto done; }
clear_buffer();
abort("Unknown character\n"); }
stuff_key((prefix << 8) | c);
done: }
}
/*
* Stuff a single keystroke into the keyboard buffer
*/
stuff_key(key)
unsigned key;
{
unsigned head;
disable();
pokew(BIOS_SEG, head = peekw(BIOS_SEG, BUFFER_HEAD), key);
if((head += 2) >= peekw(BIOS_SEG, BUFFER_END))
head = peekw(BIOS_SEG, BUFFER_START);
if(head == peekw(BIOS_SEG, BUFFER_TAIL)) {
clear_buffer();
abort("Key buffer FULL!\n"); }
if(head != peekw(BIOS_SEG, BUFFER_TAIL))
pokew(BIOS_SEG, BUFFER_HEAD, head);
enable();
}
/*
* Clear the keyboard buffer
*/
clear_buffer()
{
disable();
pokew(BIOS_SEG, BUFFER_HEAD, peekw(BIOS_SEG, BUFFER_TAIL));
enable();
}